﻿using OpenPop.Mime;
using OpenPop.Pop3;
using OpenPop.Pop3.Exceptions;
using System;
using System.Net.Mail;

namespace Rookey.Frame.Mail
{
    /// <summary>
    /// Pop3
    /// </summary>
    class Pop3Helper
    {
        #region 成员变量
        private Pop3Client pop3Client;
        private string _host;
        private int _port;
        private bool _enableSsl = true;
        private string _username;
        private string _pwd;
        #endregion

        #region 事件定义

        /// <summary>
        /// 邮件接收事件
        /// </summary>
        public EventHandler<Pop3EventArgs> EmailReceiveEvent;

        #endregion

        #region 构造函数

        /// <summary>
        /// 创建 Pop3Helper 实例
        /// </summary>
        /// <param name="host">设置 POP3 主服务器</param>
        /// <param name="port">端口号</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="enableSsl">指定 SmtpClient 是否使用安全套接字层 (SSL) 加密连接。</param>
        public Pop3Helper(string host, int port, string userName, string password, bool enableSsl = true)
        {
            MailValidatorHelper.ValideStrNullOrEmpty(host, "host");
            MailValidatorHelper.ValideStrNullOrEmpty(userName, "userName");
            MailValidatorHelper.ValideStrNullOrEmpty(password, "password");

            _host = host;
            _port = port;
            _enableSsl = enableSsl;
            _username = userName;
            _pwd = password;
            pop3Client = new Pop3Client();
        }

        /// <summary>
        /// 创建 Pop3Helper 实例
        /// </summary>
        /// <param name="type">Email类型</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="enableSsl">指定 SmtpClient 是否使用安全套接字层 (SSL) 加密连接。</param>
        public Pop3Helper(EmailType type, string userName, string password, bool enableSsl = true)
        {
            MailValidatorHelper.ValideStrNullOrEmpty(userName, "userName");
            MailValidatorHelper.ValideStrNullOrEmpty(password, "password");

            _enableSsl = enableSsl;
            _username = userName;
            _pwd = password;
            pop3Client = new Pop3Client();
            this.EmailTypeConfig(type,enableSsl);
        }
        #endregion

        #region 私有方法

        /// <summary>
        /// 根据Email类型创建SmtpClient
        /// </summary>
        /// <param name="type">Email类型</param>
        /// <param name="enableSsl">端口号会根据是否支持ssl而不同</param>
        private void EmailTypeConfig(EmailType type, bool enableSsl)
        {
            if (enableSsl) //启用ssl
            {
                _port = 995;
            }
            else
            {
                _port = 110;
            }
            switch (type)
            {
                case EmailType.Gmail:
                    {
                        _host = "pop.gmail.com";
                    }
                    break;
                case EmailType.HotMail:
                    {
                        _host = "pop3.live.com";
                    }
                    break;
                case EmailType.QQ_FoxMail:
                    {
                        _host = "pop.qq.com";
                    }
                    break;
                case EmailType.Mail_126:
                    {
                        _host = "pop.126.com ";
                    }
                    break;
                case EmailType.Mail_163:
                    {
                        _host = "pop.163.com ";
                    }
                    break;
                case EmailType.Sina:
                    {
                        _host = "pop.sina.com";
                    }
                    break;
                case EmailType.Tom:
                    {
                        _host = "pop.tom.com";
                    }
                    break;
                case EmailType.SoHu:
                    {
                        _host = "pop3.sohu.com";
                    }
                    break;
                case EmailType.Yahoo:
                    {
                        _host = "pop.mail.yahoo.com";
                    }
                    break;
                case EmailType.None:
                default:
                    {
                        throw new Exception(MailValidatorHelper.EMAIL_SMTP_TYPE_ERROR);
                    }
            }
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 接收邮件
        /// </summary>
        /// <returns>返回异常信息</returns>
        public void ReceiveMails()
        {
            try
            {
                if (pop3Client.Connected)
                    pop3Client.Disconnect();
                //连接邮件服务器
                pop3Client.Connect(_host, _port, _enableSsl);
                //用户认证
                pop3Client.Authenticate(_username, _pwd);
                //获取邮件数
                int count = pop3Client.GetMessageCount();
                for (int i = count; i >= 1; i -= 1)
                {
                    try
                    {
                        Message message = pop3Client.GetMessage(i);
                        MailMessage mailMsg = message.ToMailMessage();
                        if (EmailReceiveEvent != null)
                        {
                            EmailReceiveEvent(null, new Pop3EventArgs(mailMsg, null));
                        }
                    }
                    catch (Exception e)
                    {
                        string err = string.Format("第{0}封邮件信息获取失败: {1}\r\n堆栈信息：\r\n{2}", i, e.Message, e.StackTrace);
                        if (EmailReceiveEvent != null)
                        {
                            EmailReceiveEvent(null, new Pop3EventArgs(null, err));
                        }
                    }
                }
            }
            catch (InvalidLoginException ilex)
            {
                string err = string.Format("服务器不接收用户认证，{0}", ilex.Message);
                if (EmailReceiveEvent != null)
                {
                    EmailReceiveEvent(null, new Pop3EventArgs(null, err));
                }
            }
            catch (PopServerNotFoundException psex)
            {
                string err = string.Format("找不到对应的服务器，{0}", psex.Message);
                if (EmailReceiveEvent != null)
                {
                    EmailReceiveEvent(null, new Pop3EventArgs(null, err));
                }
            }
            catch (PopServerLockedException pslex)
            {
                string err = string.Format("邮件账户被锁定，{0}", pslex.Message);
                if (EmailReceiveEvent != null)
                {
                    EmailReceiveEvent(null, new Pop3EventArgs(null, err));
                }
            }
            catch (LoginDelayException lgex)
            {
                string err = string.Format("不允许登录，服务器强制退出，{0}", lgex.Message);
                if (EmailReceiveEvent != null)
                {
                    EmailReceiveEvent(null, new Pop3EventArgs(null, err));
                }
            }
            catch (Exception ex)
            {
                string err = string.Format("邮件接收出错：{0}", ex.Message);
                if (EmailReceiveEvent != null)
                {
                    EmailReceiveEvent(null, new Pop3EventArgs(null, err));
                }
            }
            finally
            {
                if (pop3Client.Connected)
                    try
                    {
                        pop3Client.Disconnect();
                    }
                    catch { }
            }
        }

        //public bool DeleteEmail()
        //{
            
        //}

        /// <summary>
        /// 清空邮件
        /// </summary>
        public void ClearEMail()
        {
            this.pop3Client.DeleteAllMessages();
        }

        #endregion
    }

    /// <summary>
    /// Pop3事件参数
    /// </summary>
    public class Pop3EventArgs : EventArgs
    {
        private MailMessage _message = null;

        public MailMessage Message
        {
            get { return _message; }
        }
        private string _errMsg = string.Empty;

        public string ErrMsg
        {
            get { return _errMsg; }
        }

        public Pop3EventArgs(MailMessage message, string errMsg)
        {
            _message = message;
            _errMsg = errMsg;
        }
    }
}
